<!DOCTYPE html>
<html>
<head>
	<title></title>
</head>
<script type="text/javascript" src="./lib/cuon-matrix.js"></script>
<script type="text/javascript" src="./lib/cuon-utils.js"></script>
<script type="text/javascript" src="./lib/webgl-debug.js"></script>
<script type="text/javascript" src="./lib/webgl-utils.js"></script>
<script type="text/javascript">

	var Geometry1 = new Object();
	Geometry1.vertices = new Float32Array([
   // Vertex coordinates and color(RGBA)
    -5.0,0.0,-5.0,  1.0,1.0,1.0,   -1,-1,-1,//0
    -5.0,0.0,5.0,  1.0,1.0,1.0,   -1,-1,1, //1
    5.0,0.0,-5.0,  0.0,1.0,1.0,   1,-1,-1,//2
    5.0,0.0,5.0,  1.0,1.0,1.0,	  1,-1,1, //3
    -5.0,5.0,-5.0,  1.0,1.0,1.0,   -1,1,-1,//4
    -5.0,5.0,5.0,  1.0,1.0,1.0,  -1,1,1, //5
    5.0,5.0,-5.0,  1.0,1.0,1.0,  1,1,-1, //6
    5.0,5.0,5.0,  1.0,1.0,1.0,    1,1,1, //7
      ]);

	Geometry1.indexs = new Uint8Array([
    0,1,2,
    2,1,3,//下

    4,5,6,//上
    6,5,7,

    4,0,6,//后
    6,0,2,
    
    5,1,7,//前
    7,1,3,

    0,1,5,//坐
    5,0,4,

    2,6,7,//右
    7,2,3
      ]);


	Geometry1.VSHADER_SOURCE =
	"attribute vec4 a_Position;"+
	"attribute vec4 a_Color;"+
	"attribute vec4 a_Normal;"+
	"uniform vec3 u_LightColor;"+
	"uniform vec3 u_LightDirection;"+
	"uniform mat4 u_mat4;"+
	//"uniform mat4 u_mat4l;"+
	"varying vec4 v_Color;"+
	"void main(){"+
	"gl_Position = u_mat4 * a_Position;"+
	//"vec4 normal = u_mat4l* a_Normal;"+
	"float dotf = max(dot(u_LightDirection,a_Normal.xyz),0.0);"+
	"vec3 diffuse = u_LightColor*a_Color.rgb * dotf;"+
	"if (diffuse.r <=0.0){"+
	" diffuse.r = 0.6;"+
	" diffuse.g = 0.2;"+
	"}"+
	"v_Color = vec4(diffuse,a_Color.a);"+
	"}";

	Geometry1.FSHADER_SOURCE =
	"precision mediump float;"+
	"varying vec4 v_Color;"+
	"void main(){"+
	'float d = distance(gl_PointCoord, vec2(0.5, 0.5));'+
	'if(d < 0.5) {' +  // Radius is 0.5
	'gl_FragColor = v_Color;' +
	'  } else { discard; }' +
	'}';
	 Geometry1.initVertexBuffers = function(gl){
		this.vertexBuffer = gl.createBuffer();
		if(!this.vertexBuffer){
			alert('createBuffer gvertexBuffer fail');
			return false;
		}
		this.indexBuffer = gl.createBuffer();
		if(!this.indexBuffer){
			alert('createBuffer indexBuffer fail');
			return false;
		}
		return true
	}


    Geometry1.initShader = function(gl){
    	this.program = createProgram(gl,this.VSHADER_SOURCE,this.FSHADER_SOURCE);
		if(!this.program){
			alert('Geometry1 createProgram fail')
			return;
		}
		gl.useProgram(this.program);
    	this.a_mat = gl.getUniformLocation(this.program,'u_mat4');	
		if (!this.a_mat) {
			alert('uniform u_mat4 fail');
			return false;
		}

		this.u_LightColor = gl.getUniformLocation(this.program,'u_LightColor');
		if(!this.u_LightColor){
			alert('u_LightColor fail');
			return false;
		}

		this.u_LightDirection = gl.getUniformLocation(this.program,'u_LightDirection');
		if(!this.u_LightDirection){
			alert('u_LightDirection fail');
			return;
		}

		this.a_Position = gl.getAttribLocation(this.program,'a_Position');
		if(this.a_Position <0){
			alert('a_PointSize fail')
			return false;
		}
		
		this.a_Color = gl.getAttribLocation(this.program,'a_Color');
		if(this.a_Color <0){
			alert('a_Color fail');
			return false;
		}

		this.a_Normal = gl.getAttribLocation(this.program,'a_Normal');
		if(this.a_Normal <0){
			alert('a_Normal fail');
			return false;
		}

		gl.enableVertexAttribArray(this.a_Position);
		gl.enableVertexAttribArray(this.a_Color);
		gl.enableVertexAttribArray(this.a_Normal);

		return true;
    }

  
	Geometry1.lightDirection = new Vector3([1, 4,2]);
  	Geometry1.lightDirection.normalize();     // Normalize
  	
  	Geometry1.viewMatrix = new Matrix4();
	Geometry1.viewMatrix.setPerspective(45,1,1,1000);
	Geometry1.viewMatrix.lookAt(0,0,200,0,0,0,0,1,0);

	 function ModelItem(worldPosV3,name,initPositionV3,initScaleV3,initRotateV4,animation){
		  this.name = name;//名称
		  this.frames = 0;
		  this.animation = animation
		  this.children = new Array();
		  //初始化数据
	      var initModel = new Matrix4().setIdentity();

	      if(initPositionV3!=null){
	   	 	 initModel.translate(initPositionV3[0],initPositionV3[1],initPositionV3[2]);
	      }

	     if(initRotateV4 != null){
	      	initModel.rotate(initRotateV4[0],initRotateV4[1],initRotateV4[2],initRotateV4[3]);
	      }

	      if(initScaleV3 != null){
	      	initModel.scale(initScaleV3[0],initScaleV3[1],initScaleV3[2]);
	      }

	      this.initModelMat4 = initModel;

	      this.worldMat4 = new Matrix4().translate(worldPosV3[0],worldPosV3[1],worldPosV3[2]);;

	      this.rotateMat4 = new Matrix4().setIdentity();
	      this.translateMat4 = new Matrix4().setIdentity();

	      this.rotate = function(rotateV4){
	      	this.rotateMat4.rotate(rotateV4[0],rotateV4[1],rotateV4[2],rotateV4[3]);
	      }

	      this.translate = function(translateV3){
	      	this.translateMat4.translate(translateV3[0],translateV3[1],translateV3[2]);
	      }

	  	  this.addChild = function(child){
	  	  	 child.father = this
			 this.children.push(child);
	  	  }

	  	  this.getDrawMatrix = function(viewMatrix){
	  	    var view = new Matrix4().set(viewMatrix);
	  	    var fatherModle = new Matrix4().setIdentity();
	  	    if(this.father!=null){
	  	    	fatherModle.set(this.father.translateMat4).multiply(this.father.rotateMat4);
	  	    }
	  	    var translate = new Matrix4().set(this.translateMat4);
	  	   	var world = new Matrix4().set(this.worldMat4);
	  	   	var rotate = new Matrix4().set(this.rotateMat4);
	  	   	var init = new Matrix4().set(this.initModelMat4);

	  	   	
	  	  	return view.multiply(fatherModle.multiply(translate.multiply(world.multiply(rotate.multiply(init)))));
	  	  	//return view.multiply(translate.multiply(world.multiply(rotate.multiply(init))));
	  	  }

	  	  this.draw = function(gl,viewMatrix,u_mat,n){
	  	  	if (this.animation!=null){
	  	  		this.animation();
	  	  	}
	  	  	//console.log("drow" +this.name+"\n");
	  	  	gl.polygonOffset(1.0, 1.0);          //
  	  		gl.uniformMatrix4fv(u_mat,false,this.getDrawMatrix(viewMatrix).elements);
			gl.drawElements(gl.TRIANGLES,n,gl.UNSIGNED_BYTE,0);
			for (var i = 0; i < this.children.length; ++i) {
			  this.children[i].draw(gl,viewMatrix,u_mat,n);
			}
	  	  }

	  	  this.getChild = function(name){
	  	  	for (var i = 0; i < this.children.length; ++i) {
	  	  		if(this.children[i].name == name)
	  	  			return this.children[i];
			}	
			return null;
	  	  }
	}

	Geometry1.initRobot = function(){
		//(worldPosV3,name,initPositionV3,initScaleV3,initRotateV4){

		this.robot = new ModelItem([0,0,0],"body",[0,0,0],[4,5,1],null);

		var leftLeg = new ModelItem([-10,0,0],"leftLeg",[0,-5,0],[1,10,0.9],null);
		this.robot.addChild(leftLeg);

		var rightLeg = new ModelItem([10,0,0],"rightLeg",[0,-5,0],[1,10,0.9],null);
		this.robot.addChild(rightLeg);


		var leftarm = new ModelItem([-18,22,0],"leftarm",[-5,-3,0],[3,1.2,0.5],[30,0,0,1]);
		this.robot.addChild(leftarm);

		var rightarm = new ModelItem([18,22,0],"rightarm",[5,-3,0],[3,1.2,0.5],[-30,0,0,1]);
		this.robot.addChild(rightarm);

		var head = new ModelItem([0,25,0],"head",[0,0,0],[1.5,2,1],null);
		this.robot.addChild(head);

		
	}

	Geometry1.initHandlers = function(){
		Geometry1.dragging = false;
		Geometry1.mousepos = [0,0];
		Geometry1.canvas.onmousedown = function(ev){
			Geometry1.dragging =true;
			Geometry1.mousepos[0] =ev.clientX;
			Geometry1.mousepos[1] =ev.clientY;
		}

		Geometry1.canvas.onmouseup = function(ev){
			Geometry1.dragging = false;
		}

		Geometry1.canvas.onmousemove = function(ev){
			var x = ev.clientX, y = ev.clientY;
		    if (Geometry1.dragging) {
		      var factor = 200/Geometry1.canvas.height; // The rotation ratio
		      var dx = factor * (x - Geometry1.mousepos[0]);
		      var dy = factor * (y - Geometry1.mousepos[1]);
		      Geometry1.robot.rotate([Math.max(Math.min(dy, 90.0), -90.0),1,0,0]);
		      Geometry1.robot.rotate([dx,0,1,0]);
		    }
		    Geometry1.mousepos[0] =ev.clientX;
			Geometry1.mousepos[1] =ev.clientY;
		}
	}

	Geometry1.draw = function(gl,frames){
		
		gl.bindBuffer(gl.ARRAY_BUFFER,this.vertexBuffer);
		gl.bufferData(gl.ARRAY_BUFFER,this.vertices,gl.STATIC_DRAW);
		
		var Fsize = this.vertices.BYTES_PER_ELEMENT;
		gl.vertexAttribPointer(this.a_Position,3,gl.FLOAT,false,Fsize*9,0);
		gl.vertexAttribPointer(this.a_Color,3,gl.FLOAT,false,Fsize*9,Fsize*3);
		gl.vertexAttribPointer(this.a_Normal,3,gl.FLOAT,false,Fsize*9,Fsize*6);
			
		gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,this.indexBuffer);
		gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,this.indexs,gl.STATIC_DRAW);

		gl.uniform3f(this.u_LightColor,0.8,0.4,0.3);
		gl.uniform3fv(this.u_LightDirection,this.lightDirection.elements);

		if(frames % 2 ==0){
			//this.robot.getChild("head").rotate([-1,0,1,0]);
			//this.robot.getChild("rightLeg").rotate([1,0,0,1]);
			this.robot.rotate([1,0,1,0]);
		}
		//this.robot.getChild("leftarm").draw(gl,this.viewMatrix,this.a_mat,this.indexs.length);
		this.robot.draw(gl,this.viewMatrix,this.a_mat,this.indexs.length)

		gl.bindBuffer(gl.ARRAY_BUFFER,null);
	}
;
	function start () {
	
		Geometry1.canvas = document.getElementById("webgl");
		var gl = getWebGLContext(Geometry1.canvas);
		if (!gl){
			alert('gl fail');
			return;
		}

		if(!Geometry1.initShader(gl)){
			alert('Geometry1 initShaderParm fail')
			return;
		}

		if (!Geometry1.initVertexBuffers(gl)){
			alert('Geometry1 initVertexBuffers fail');
			return;
		}
		Geometry1.initHandlers();
		// if(!Geometry1.initTexture(gl)){
		// 	alert('initTexture fail');
		// 	return;
		// }
		Geometry1.initRobot();

		var frames = 0
		//gl.viewport(50,50,100,100);
		gl.enable(gl.POLYGON_OFFSET_FILL);
		gl.enable(gl.DEPTH_TEST);
		gl.clearColor(0,0,0,0.02);
		function renderer(){
			frames++;
			render(gl,frames);
			requestAnimationFrame(renderer)
		}
		renderer();
	}

	function render(gl,frames){

		gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
		Geometry1.draw(gl,frames);		
	}



</script>
<body onload="start()">
<canvas id="webgl" width="500" height="500"></canvas>
</body>
</html>